Skip to content

fix(native-api): 修复 Gemini embedding 透传至 Vertex AI 风格上游的协议适配问题#238

Merged
ThreeFish-AI merged 2 commits into
feature/1.x.xfrom
ThreeFish-AI/fix-gemini-batch-embed-v1
May 12, 2026
Merged

fix(native-api): 修复 Gemini embedding 透传至 Vertex AI 风格上游的协议适配问题#238
ThreeFish-AI merged 2 commits into
feature/1.x.xfrom
ThreeFish-AI/fix-gemini-batch-embed-v1

Conversation

@ThreeFish-AI
Copy link
Copy Markdown
Owner

背景

通过本代理调用 Gemini embedding 模型(如 gemini-embedding-2-previewgemini-embedding-001text-embedding-005)时,上游返回 400 错误:

```
litellm.BadRequestError: GeminiException BadRequestError -
{"error":{"message":"request body doesn't contain valid prompts"}}
POST /api/gemini/v1beta/models/gemini-embedding-001:batchEmbedContents 400
```

根因

  1. 上游协议差异:实际上游(如 llms.as-in.io 这类 Vertex AI 风格网关)只接受 Vertex AI 格式 v1beta1/publishers/google/models/{model}:embedContent + {"content": ...} 单体请求体,不支持 Google AI Studio 的 batchEmbedContents 端点
  2. litellm 行为偏差:litellm 按 Google AI Studio 格式发送 v1beta/models/{model}:batchEmbedContents + {"requests": [...]} 批量格式
  3. litellm bug_check_custom_proxy() 在自定义 api_base 场景下会丢失 v1beta/ 版本前缀(参考 litellm issue #17759),使代理原有的 OperationClassifier 正则失配

改动

  • src/coding/proxy/native_api/handler.py:新增 Gemini embedding Vertex AI 适配分支
    • 仅当 provider == "gemini"operation ∈ {"embedding", "embedding.batch"}、且 base_url 非官方 generativelanguage.googleapis.com 时启用
    • embedContent → 重写路径为 v1beta1/publishers/google/models/{model}:embedContent,剥离 body 中的 model 字段
    • batchEmbedContents → 拆分为并发 embedContent 调用(asyncio.gather),聚合响应为 {"embeddings": [...]} 返回
    • 用量抽取累加各子请求的 usageMetadata
  • src/coding/proxy/native_api/operation.py:放宽 Gemini 路径正则中的 v1(?:beta1?)?/ 段为可选,兼容 litellm 丢失版本前缀的异常路径
  • tests/test_native_api_handler.py:新增 3 个回归测试覆盖单次 / 批量 / 官方上游透传不变三类场景
  • docs/issue.md:补充该 Issue 的复盘条目

风险控制

  • 协议适配层只对非官方上游生效,官方 generativelanguage.googleapis.com 仍走字节级透传,无任何回归影响
  • 现有 17 个 native_api 测试全部通过,新增 3 个测试覆盖核心适配场景
  • 完整测试套件 1450 个测试通过,无回归

验证

  • ✅ 单元测试:pytest tests/ 1450 通过
  • ✅ 真实链路:用 litellm embedding(model='gemini/gemini-embedding-2-preview', api_base=..., api_key=...) 通过本地代理调用,单输入 / 多输入(3 文本)均成功返回 3072 维 embedding

🤖 Generated with Claude Code, CodeX, Gemini

- 在非官方上游场景下,将 Google AI Studio 格式(v1beta/models/{model}:batchEmbedContents)
  自动转换为 Vertex AI 格式(v1beta1/publishers/google/models/{model}:embedContent)
- batchEmbedContents 拆分为并发 embedContent 调用,聚合响应为 {"embeddings": [...]}
- 放宽 OperationClassifier 路径正则,兼容 litellm _check_custom_proxy 丢失 v1beta 前缀的 bug
- 官方 generativelanguage.googleapis.com 仍走字节级透传,无回归影响
- 补充 3 个回归测试 + docs/issue.md 复盘条目

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
在 _vertex_batch_embed._single 中为 client.send() 添加与 _vertex_single_embed
一致的 httpx 网络异常处理(TimeoutException/ConnectError/ReadError/RemoteProtocolError),
确保子请求超时或连接失败时返回 502 而非触发未处理异常。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
@ThreeFish-AI ThreeFish-AI merged commit f481fe6 into feature/1.x.x May 12, 2026
6 checks passed
@ThreeFish-AI ThreeFish-AI deleted the ThreeFish-AI/fix-gemini-batch-embed-v1 branch May 13, 2026 02:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant